#ifndef SCVISION_H
#define SCVISION_H

#include "commonmethod.h"
#include "enumhelper.h"
#include "errorHandling/silicolerror.h"
#include "scvision_global.h"
#include <QImage>

struct SCVISIONSHARED_EXPORT PRResultStruct
{
public:
    PRResultStruct() : x(0), y(0), theta(0), width(0), height(0) {}

    PRResultStruct(double x, double y, double theta, double width, double height)
        : x(x), y(y), theta(theta), width(width), height(height)
    {
    }

    QString toString() const
    {
        return QString("x: %1, y: %2, theta: %3, ori_x: %4, ori_y: %5").arg(x).arg(y).arg(theta).arg(ori_x).arg(ori_y);
    }

    // x y 表示用户自定义的点到pattern中心的偏移
    double x;
    double y;

    // ori_x ori_y表示pattern中心到图像中心的偏移
    double ori_x;
    double ori_y;

    double theta;
    double width;
    double height;
};

struct SCVISIONSHARED_EXPORT PRResultImageInfo
{
public:
    PRResultImageInfo()
        : rect_x(0),
          rect_y(0),
          rect_ori_x(0),
          rect_ori_y(0),
          rect_width(0),
          rect_height(0),
          rect_angle(0),
          result_ori_x(0),
          result_ori_y(0),
          result_x(0),
          result_y(0),
          resultString(""),
          radius(0),
          prType(0)
    {
    }

    // x y Rectangle upper left point pixel coordinate
    double rect_x;
    double rect_y;

    // ori x y Rectangle Mass center of the rectangle
    double rect_ori_x;
    double rect_ori_y;

    // Rectangle width height in pixel unit
    double rect_width;
    double rect_height;

    // Angle of the rectangle
    double rect_angle;

    // PR Result Original Point in pixel unit (without offset)

    double result_ori_x;
    double result_ori_y;

    // PR Result with user defined offset

    double result_x;
    double result_y;

    // Circle Related

    double radius;

    // PrType

    int prType;

    // Any result string
    QString resultString;
};

class SCVISIONSHARED_EXPORT SCVision : public QObject
{
    Q_OBJECT
public:
    enum PrType
    {
        Generic_NCC_Template_Matching,
        Edge_Template_Matching,
        Circle_Edge_Template_Matching
    };
    Q_ENUM(PrType)

    static EnumHelper<PrType> &PrTypeEnumInfo()
    {
        static EnumHelper<PrType> instance(staticMetaObject, "PrType");
        return instance;
    }

    virtual ~SCVision() {}

    ///
    /// \brief performPr
    /// \param image input image
    /// \param prName pr file name
    /// \param resultImageInfo output result image info, will be passed into 'drawResultImage' function next in another
    /// thread to draw result image.
    /// \param prResult output pr result
    /// \return
    /// \exceptions GeneraError will be thrown if any error occured.
    ///
    virtual bool performPr(QImage &image,
                           QString prName,
                           PrType prType,
                           double objectScore,
                           PRResultImageInfo &resultImageInfo,
                           PRResultStruct &prResult,
                           int roiRowIndex = 0,
                           int roiColIndex = 0,
                           QVariantMap args = QVariantMap())
        = 0;

    virtual void drawResultImage(QImage &image, PRResultImageInfo &resultImageInfo) = 0;

    ///
    /// \brief glueCheck
    /// \param imageBefore  input image, before glue shot
    /// \param imageAfter   input image, after glue shot
    /// \param resoultion   pixel to mm
    /// \param resultImage  output image, will be shown on UI
    /// \return
    ///
    virtual bool glueCheck(QImage &imageBefore,
                           QImage &imageAfter,
                           double resoultion,
                           QImage &resultImage,
                           double &outMinGlueWidth,
                           double &outMaxGlueWidth,
                           double &outMaxAvgGlueWidth)
        = 0;

    ///
    /// \exceptions SilicolAbort will be thrown if any error occured.
    ///
    virtual QVector<QPointF> readDispensePath(QString fileName) = 0;

    virtual bool checkDongle()
    {
        return true;
    }
};

#endif    // SCVISION_H
